
#include "usart.h"
#include "stm32f1xx_hal.h"
#include "dtuconfig.h"
#include "nb.h"

//PSM_MODE 1 = ON  0 = OFF
#define PSM_MODE 1
//EDRX_MODE 1 = ON  0 = OFF
#define EDRX_MODE 1

#define NBRXFLAG     NB_UART_RX.flag
#define NBRXBUFF     NB_UART_RX.buff
#define NBRXLEN      NB_UART_RX.len
#define NBSEND(a, b) usart_send_data(&NB_UART, a, b)

#define NB_BUFF_SIZE        UART3_BUFF_SIZE
#define NBHexStrTxBuffer    NBRXBUFF
#define NBHexStrTxBufferLen NBRXLEN
#define NBPayLoad           FramBuff
#define NBPayLoadSize       FrameSize

#define INT_MAX ((int)0x7FFFFFFF)
#define INT_MIN ((int)0x80000000)

static uint8_t socketid = 0;

#define NB_Reset()                                                           \
    {                                                                        \
        HAL_GPIO_WritePin(NB_Reset_GPIO_Port, NB_Reset_Pin, GPIO_PIN_SET);   \
        HAL_Delay(200);                                                      \
        HAL_GPIO_WritePin(NB_Reset_GPIO_Port, NB_Reset_Pin, GPIO_PIN_RESET); \
    }

extern uint8_t  FramBuff[255];
extern uint16_t FrameSize;

typedef struct
{
    int16_t  SignalPower;
    int16_t  SNR;
    uint32_t CellID;
    uint8_t  SignalECL;
} NB_ModuleInfo_TypeDef;

NB_ModuleInfo_TypeDef NB_ModuleInfo;

int32_t myatoi(const char* str, const int len)
{
    int       minus = 0;
    long long result = 0;
    int       rst = 0;

    if (str == NULL)
        return 0;
    while (*str == ' ')
        str++;
    if (*str == '-') {
        minus = 1;
        str++;
    } else if (*str == '+')
        str++;
    if (*str < '0' || *str > '9')
        return 0;

    while ((*str >= '0' && *str <= '9') && (rst < len)) {
        result = result * 10 + *str - '0';
        if ((minus && result > INT_MAX + 1LL) || (!minus && result > INT_MAX)) {
            return 0;
        }

        str++;
        rst++;
    }

    if (minus)
        result *= -1;
    return (int)result;
}

uint8_t NB_CheckPoweron(void)
{
    uint8_t len, retry;
    retry = 50;
    while (retry) {
        retry--;
        NBRXFLAG = 0;
        len = sprintf((char*)NBRXBUFF, "AT\r\n");
        NBSEND(NBRXBUFF, len);
        HAL_Delay(200);
        if (NBRXFLAG) {
            NBRXFLAG = 0;
            if (('O' == NBRXBUFF[2]) && ('K' == NBRXBUFF[3])) {
                return 1;
            }
        }
    }
    return 0;
}
uint8_t NB_GetSignal(void)
{
    uint8_t len;
    uint8_t signal = 0;
    char*   pchar;
    NBRXFLAG = 0;
    len = sprintf((char*)NBRXBUFF, "AT+CSQ\r\n");
    NBSEND(NBRXBUFF, len);
    HAL_Delay(300);
    if (NBRXFLAG) {
        NBRXFLAG = 0;
        //UART_SendData(USART1,NBRXBUFF,NBRXLEN); //send to PC.
        NBRXBUFF[NBRXLEN] = 0;
        pchar = strchr((char*)NBRXBUFF, ':');
        signal = myatoi(pchar + 1, 2);
        return signal;
    }
    return 99;
}

void NB_GetConnectionInfo(void)
{
    char* pchar;
    int   temp;
    NBSEND((uint8_t*)"AT+NUESTATS\r\n", 13);
    HAL_Delay(200);
    if (NBRXFLAG) {
        NBRXFLAG = 0;
        if (NBRXLEN < NB_BUFF_SIZE) {
            NBRXBUFF[NBRXLEN] = 0;
            pchar = strstr((char*)NBRXBUFF, "Signal power");
            if (pchar) {
                temp = myatoi(pchar + 13, 10);
                NB_ModuleInfo.SignalPower = temp / 10;
            }
            pchar = strstr((char*)NBRXBUFF, "SNR");
            if (pchar) {
                temp = myatoi(pchar + 4, 10);
                NB_ModuleInfo.SNR = temp;
            }
            pchar = strstr((char*)NBRXBUFF, "ECL");
            if (pchar) {
                temp = myatoi(pchar + 4, 10);
                NB_ModuleInfo.SignalECL = temp;
            }
            pchar = strstr((char*)NBRXBUFF, "Cell ID");
            if (pchar) {
                temp = myatoi(pchar + 8, 20);
                NB_ModuleInfo.CellID = temp;
            }
        }
    }
}

void NB_SetIndication(void)
{
    uint8_t len;
    len = sprintf((char*)NBRXBUFF, "AT+NSMI=1\r\n");
    NBSEND(NBRXBUFF, len);
    HAL_Delay(300);
}
/** @WJ 2019-4-22
  * @brief  This function is used to indicate the status of NB net connect 
  * @param  None
  * @retval 1:OnNet  0:OffNet
  */
uint8_t NB_CheckNetStatus(void)
{
    uint16_t len = 0;
    len = sprintf((char*)NBRXBUFF, "AT+CGATT?\r\n");
    NBRXFLAG = 0;
    NBSEND(NBRXBUFF, len);
    len = 50;
    while (!NBRXFLAG && len--) {
        HAL_Delay(10);
    }
    if (NBRXFLAG) {
        NBRXFLAG = 0;
        if (strstr((char*)NBRXBUFF, ":1")) {
            return 1;
        }
    }
    return 0;
}

uint8_t NB_ModuleInit(void)
{
    uint8_t len, retry = 10;
    NB_Reset();
    HAL_Delay(2000);
    if (!NB_CheckPoweron()) {
        return 0;
    }

    NBRXFLAG = 0;
    NBRXLEN = 0;
    len = sprintf((char*)NBRXBUFF, "AT+NCDP?\r\n");
    NBSEND(NBRXBUFF, len);
    HAL_Delay(300);
    NBRXBUFF[NBRXLEN] = 0;
    sprintf((char*)(NBRXBUFF + 100), "%u.%u.%u.%u,%u", RadioCfgInfo.Paras.NB.IP1, RadioCfgInfo.Paras.NB.IP2, RadioCfgInfo.Paras.NB.IP3, RadioCfgInfo.Paras.NB.IP4, RadioCfgInfo.Paras.NB.Port);
    if (!strstr((char*)NBRXBUFF, (char*)(NBRXBUFF + 100))) {
        len = sprintf((char*)NBRXBUFF, "AT+NCDP=%u.%u.%u.%u,%u\r\n", RadioCfgInfo.Paras.NB.IP1, RadioCfgInfo.Paras.NB.IP2, RadioCfgInfo.Paras.NB.IP3, RadioCfgInfo.Paras.NB.IP4, RadioCfgInfo.Paras.NB.Port);
        NBSEND(NBRXBUFF, len);
        HAL_Delay(300);

        len = sprintf((char*)NBRXBUFF, "AT+NRB\r\n"); //reboot
        NBSEND(NBRXBUFF, len);
        HAL_Delay(3000);
    }

    if (!NB_CheckPoweron()) {
        return 0;
    }

    len = sprintf((char*)NBRXBUFF, "AT+CGDCONT=1,\"IP\",\"CTNB\"\r\n");
    NBSEND(NBRXBUFF, len);
    HAL_Delay(500);

    len = sprintf((char*)NBRXBUFF, "AT+NSMI=1\r\n");
    NBSEND(NBRXBUFF, len);
    HAL_Delay(500);

    len = sprintf((char*)NBRXBUFF, "AT+CMEE=1\r\n");
    NBSEND(NBRXBUFF, len);
    HAL_Delay(500);

    len = sprintf((char*)NBRXBUFF, "AT+NNMI=0\r\n");
    NBSEND(NBRXBUFF, len);
    HAL_Delay(500);

    //len = sprintf((char *)NBRXBUFF,"AT+CPSMS=%d,,,01000011,00100001\r\n",PSM_MODE);
    len = sprintf((char*)NBRXBUFF, "AT+CPSMS=%d,,,01000011,00100001\r\n", RadioCfgInfo.Paras.NB.PSM);
    NBSEND(NBRXBUFF, len);
    HAL_Delay(500);

    //len = sprintf((char *)NBRXBUFF,"AT+CEDRXS=%d,5,0101\r\n",EDRX_MODE);
    len = sprintf((char*)NBRXBUFF, "AT+CEDRXS=%d,5,0101\r\n", RadioCfgInfo.Paras.NB.eDRX);
    NBSEND(NBRXBUFF, len);
    HAL_Delay(500);

    retry = 100; //5min
    while (retry) {
        retry--;
        len = sprintf((char*)NBRXBUFF, "AT+CGATT?\r\n");
        NBSEND(NBRXBUFF, len);
        HAL_Delay(300);
        if (strstr((char*)NBRXBUFF, ":1")) {
            retry = 1;
            break;
        }
        HAL_Delay(3000);
        msg_printf("NB init-waiting for Net\r\n");

        if (DEBUG_UART_RX.flag && DEBUG_UART_RX.len > 2) {
            retry = 0;
            break;
        }
    }

    return retry;
}

uint8_t NB_SendFrame(uint8_t* pHexdata, uint16_t datalen)
{
    uint8_t  retry, resend = 2, csq;
    uint16_t i, len;

    NB_GetConnectionInfo(); //get nuestatus every time.
    csq = NB_GetSignal();   //get CSQ.
    while (resend--)        //sedend cnt
    {
        memset(NBHexStrTxBuffer, 0, NBHexStrTxBufferLen);
        len = sprintf((char*)NBHexStrTxBuffer, "AT+NMGS=%d,", datalen + 1);

//connection info
#if 1
        len = sprintf((char*)NBHexStrTxBuffer, "AT+NMGS=%d,", datalen + 1 + 10);
        //signal power
        sprintf((char*)NBHexStrTxBuffer + len, "%x%x%x%x", (NB_ModuleInfo.SignalPower >> 12) & 0x0f, (NB_ModuleInfo.SignalPower >> 8) & 0x0f, (NB_ModuleInfo.SignalPower >> 4) & 0x0f, NB_ModuleInfo.SignalPower & 0x0f);
        len += 4;
        //snr
        sprintf((char*)NBHexStrTxBuffer + len, "%x%x%x%x", (NB_ModuleInfo.SNR >> 12) & 0x0f, (NB_ModuleInfo.SNR >> 8) & 0x0f, (NB_ModuleInfo.SNR >> 4) & 0x0f, NB_ModuleInfo.SNR & 0x0f);
        len += 4;
        //cell id
        sprintf((char*)NBHexStrTxBuffer + len, "%x%x%x%x%x%x%x%x", (NB_ModuleInfo.CellID >> 28) & 0x0f, (NB_ModuleInfo.CellID >> 24) & 0x0f, (NB_ModuleInfo.CellID >> 20) & 0x0f, (NB_ModuleInfo.CellID >> 16) & 0x0f, (NB_ModuleInfo.CellID >> 12) & 0x0f, (NB_ModuleInfo.CellID >> 8) & 0x0f, (NB_ModuleInfo.CellID >> 4) & 0x0f, NB_ModuleInfo.CellID & 0x0f);
        len += 8;
        //ecl
        sprintf((char*)NBHexStrTxBuffer + len, "%x%x", (NB_ModuleInfo.SignalECL >> 4) & 0x0f, NB_ModuleInfo.SignalECL & 0x0f);
        len += 2;
        //battery level
        sprintf((char*)NBHexStrTxBuffer + len, "%.2x", csq); //Notice: for CSQ!!!
        len += 2;
#endif

        //variable length,first byte need to be the datalen
        sprintf((char*)NBHexStrTxBuffer + len, "%x%x", datalen >> 4, datalen & 0x0f);
        len += 2;

        for (i = 0; i < datalen; i++) {
            sprintf((char*)(NBHexStrTxBuffer + len + 2 * i), "%x%x", *(pHexdata + i) >> 4, *(pHexdata + i) & 0x0f);
        }
        len += (datalen << 1);

        NBHexStrTxBuffer[len++] = 0x0d;
        NBHexStrTxBuffer[len++] = 0x0a;
        NBHexStrTxBuffer[len] = 0;
        NBSEND((uint8_t*)NBHexStrTxBuffer, len);

        msg_printf("NB_TxBuff:");
        for (i = 0; i < len; i++) {
            msg_printf("%c", NBHexStrTxBuffer[i]);
        }
        msg_printf("\r\n");

        NBRXFLAG = 0;
        retry = 0;
        while ((!NBRXFLAG) && (retry < 200)) {
            retry++;
            HAL_Delay(10);
        }

        //msg_printf("NBRXBUFF=%s\r\n",NBRXBUFF);

        if (strstr((char*)NBRXBUFF, "OK")) {
            msg_printf("send done, %d Byte\r\n", len);
            memset(NBRXBUFF, 0, NB_BUFF_SIZE);
            return 1;
        } else {
            msg_printf("send fail, %d Byte\r\n", len);
            msg_printf("%s\r\n", NBRXBUFF);
            memset(NBRXBUFF, 0, NB_BUFF_SIZE);
            return 0;
        }
    }
    return 0;
}

uint8_t NB_GetModuleBuffData(void)
{
    uint16_t dt = 0, i = 0;
    int32_t  len = 0;
    char*    pchar;
    uint8_t  temp8;
    NBRXFLAG = 0;
    /*
    NBSEND((uint8_t *)"AT+NNMI?\r\n",10);
    while(!NBRXFLAG && dt< 200)
    {
        HAL_Delay(10);
        dt++;
    }
    if(NBRXLEN < NB_BUFF_SIZE)
    {
        NBRXBUFF[NBRXLEN] = 0;
    }
    if(NBRXFLAG)
    {
        NBRXFLAG = 0;
        msg_printf("NNMI: %s\r\n",NBRXBUFF);
    }
    memset(NBRXBUFF,0,NB_BUFF_SIZE);
    */

    NBSEND((uint8_t*)"AT+NMGR\r\n", 9);
    while (!NBRXFLAG && dt < 200) {
        HAL_Delay(10);
        dt++;
    }
    if (NBRXLEN < NB_BUFF_SIZE) {
        NBRXBUFF[NBRXLEN] = 0;
    } else {
        return 0;
    }
    if (NBRXFLAG) {
        NBRXFLAG = 0;
        pchar = strchr((char*)NBRXBUFF, ',');
        if (pchar) {
            len = myatoi((char*)(NBRXBUFF + 2), 5);
            if (!len) {
                return 0;
            }
            if (len > 255) {
                return 0;
            }
            NBPayLoadSize = len;
            //msg_printf("NBPayLoadSize = %d\r\n",NBPayLoadSize);
            pchar++;
            for (i = 0; i < len; i++) {
                if (pchar[0] >= '0' && pchar[0] <= '9') {
                    temp8 = (pchar[0] - '0') << 4;
                } else if (pchar[0] >= 'A' && pchar[0] <= 'F') {
                    temp8 = (pchar[0] - 'A' + 10) << 4;
                } else if (pchar[0] >= 'a' && pchar[0] <= 'f') {
                    temp8 = (pchar[0] - 'a' + 10) << 4;
                } else {
                    break;
                }

                if (pchar[1] >= '0' && pchar[1] <= '9') {
                    temp8 |= (pchar[1] - '0');
                } else if (pchar[1] >= 'A' && pchar[1] <= 'F') {
                    temp8 |= (pchar[1] - 'A' + 10);
                } else if (pchar[1] >= 'a' && pchar[1] <= 'f') {
                    temp8 |= (pchar[1] - 'a' + 10);
                } else {
                    break;
                }
                NBPayLoad[i] = temp8;
                pchar += 2;
            }
            if (i == len) {
                return 1;
            }
        }
    }
    return 0;
}

uint8_t NB_ProcessRxData(void)
{
    char*    pchar;
    uint16_t len, i;
    uint8_t  temp8;

    if (NBRXLEN < NB_BUFF_SIZE) {
        NBRXBUFF[NBRXLEN] = 0;
    } else {
        return 0;
    }

    pchar = strstr((char*)NBRXBUFF, "+NNMI");
    if (pchar) {
        len = myatoi(pchar + 6, 10);
        NBPayLoadSize = len;
        pchar = strchr(pchar, ',');
        if (pchar) {
            pchar++;
            for (i = 0; i < len; i++) {
                if (pchar[0] >= '0' && pchar[0] <= '9') {
                    temp8 = (pchar[0] - '0') << 4;
                } else if (pchar[0] >= 'A' && pchar[0] <= 'F') {
                    temp8 = (pchar[0] - 'A' + 10) << 4;
                } else if (pchar[0] >= 'a' && pchar[0] <= 'f') {
                    temp8 = (pchar[0] - 'a' + 10) << 4;
                } else {
                    break;
                }

                if (pchar[1] >= '0' && pchar[1] <= '9') {
                    temp8 |= (pchar[1] - '0');
                } else if (pchar[1] >= 'A' && pchar[1] <= 'F') {
                    temp8 |= (pchar[1] - 'A' + 10);
                } else if (pchar[1] >= 'a' && pchar[1] <= 'f') {
                    temp8 |= (pchar[1] - 'a' + 10);
                } else {
                    break;
                }

                NBPayLoad[i] = temp8;
                pchar += 2;
            }
            if (i == len) {
                return 1;
            }
        }
    }
    return 0;
}

uint8_t NB_test(void)
{
    uint8_t  retry, signal;
    uint16_t i, len;
    signal = NB_GetSignal();
    msg_printf("NB Test,RSSI:%u\r\n", signal);
    i = sprintf((char*)NBRXBUFF, "AT+NMGS=128,000000%x%x", signal >> 4, signal & 0x0f);
    for (len = i; len < i + 248; len++) {
        NBRXBUFF[len] = 0x36;
    }
    NBRXBUFF[len++] = 0x0d;
    NBRXBUFF[len++] = 0x0a;
    NBRXFLAG = 0;
    NBSEND(NBRXBUFF, len);
    retry = 0;
    while ((!NBRXFLAG) && (retry < 200)) {
        retry++;
        HAL_Delay(10);
    }
    if (NBRXLEN < NB_BUFF_SIZE) {
        NBRXBUFF[NBRXLEN] = 0;
    } else {
        return 0;
    }
    if (strstr((char*)NBRXBUFF, "OK")) {
        usart_send_data(&DEBUG_UART, NBRXBUFF, NBRXLEN);
        return 1;
    } else {
        msg_printf("Send failed\r\n", signal);
        return 0;
    }
}

/******     NB TCP Function     *******/

/**
  * @brief  This function is NB_TCP_Connect
  * @param  None
  * @retval 0:OK  1:Error
  */
static uint8_t NB_TCP_Connect(void)
{
    uint16_t len = 0, retry = 0;
    NBRXFLAG = 0;
    NBRXLEN = 0;
    memset((uint8_t*)NBRXBUFF, 0, NB_BUFF_SIZE);
    if (RadioCfgInfo.Paras.NBTCP.Net == NET_UDP) {
        len = sprintf((char*)NBRXBUFF, "AT+NSOCR=\"DGRAM\",17,2334,1\r\n");
        msg_printf("NB_UDP Creat Socket...");
    } else {
        len = sprintf((char*)NBRXBUFF, "AT+NSOCR=\"STREAM\",6,6003,1\r\n");
        msg_printf("NB_TCP Creat Socket...");
    }

    NBSEND(NBRXBUFF, len);
    memset((uint8_t*)NBRXBUFF, 0, len);
    retry = 0;
    while (!NBRXFLAG && retry < 10) {
        retry++;
        HAL_Delay(200);
    }
    if (NBRXFLAG) {
        NBRXFLAG = 0;
        if (!strstr((char*)NBRXBUFF, (char*)"OK")) {
            msg_printf("Creat Socket...Error\r\n");
            return 0;
        } else {
            socketid = (uint8_t)NBRXBUFF[2] - '0';
            msg_printf("Creat Socket...Done\r\n");
            if (RadioCfgInfo.Paras.NBTCP.Net == NET_UDP) {
                return 1;
            }
        }
    } else {
        return 0;
    }

    HAL_Delay(500);
    NBRXFLAG = 0;
    memset(NBRXBUFF, 0, NBRXLEN);

    len = sprintf((char*)NBRXBUFF, "AT+NSOCO=%d,%d.%d.%d.%d,%d\r\n", socketid, RadioCfgInfo.Paras.NB.IP1, RadioCfgInfo.Paras.NB.IP2, RadioCfgInfo.Paras.NB.IP3, RadioCfgInfo.Paras.NB.IP4, RadioCfgInfo.Paras.NB.Port);

    NBSEND(NBRXBUFF, len); //Socket connect to ip port
    memset(NBRXBUFF, 0, len);

    msg_printf("NB_TCP Socket connect to %d.%d.%d.%d,%d\r\n", RadioCfgInfo.Paras.NB.IP1, RadioCfgInfo.Paras.NB.IP2, RadioCfgInfo.Paras.NB.IP3, RadioCfgInfo.Paras.NB.IP4, RadioCfgInfo.Paras.NB.Port);

    retry = 0;
    while (!NBRXFLAG && retry < 10) {
        retry++;
        HAL_Delay(200);
    }
    if (NBRXFLAG) {
        NBRXFLAG = 0;
        if (!strstr((char*)NBRXBUFF, (char*)"OK")) {
            return 0;
        } else {
            return 1;
        }
    } else {
        return 0;
    }
}
/**
  * @brief  This function is NB_TCP_Disconnect
  * @param  None
  * @retval 0:OK  1:Error
  */
static uint8_t NB_TCP_Disconnect(void)
{
    uint16_t len = 0, retry = 0;
    NBRXFLAG = 0;
    len = sprintf((char*)NBRXBUFF, "AT+NSOCL=%d\r\n", socketid);
    NBSEND(NBRXBUFF, len);
    retry = 0;
    while (!NBRXFLAG && retry < 10) {
        retry++;
        HAL_Delay(200);
    }
    if (NBRXFLAG) {
        NBRXFLAG = 0;
        if (!strstr((char*)NBRXBUFF, (char*)"OK")) {
            return 0;
        } else {
            return 1;
        }
    } else {
        return 0;
    }
}

/**
  * @brief  This function is used to reboot NB Module
  * @param  None
  * @retval 1:OK  0:Error
  */
static uint8_t NB_TCP_Restart(void)
{
    uint16_t len = 0;
    uint8_t  i = 0;
    while (1) {
        NBRXFLAG = 0;
        memset(NBRXBUFF, 0, NB_BUFF_SIZE);
        len = sprintf((char*)NBRXBUFF, "AT+NRB\r\n");
        NBSEND(NBRXBUFF, len);
        HAL_Delay(1000);

        if (NBRXFLAG) {
            NBRXFLAG = 0;
            if (strstr((char*)NBRXBUFF, (char*)"OK")) {
                memset((uint8_t*)NBRXBUFF, 0, NB_BUFF_SIZE);
                return 1;
            }
        }
        i++;
        if (i == 10) {
            return 0;
        }
    }
}

/**
  * @brief  This function is used to initialize the NB module
  * @param  None
  * @retval 1:OK  0:Error
  */
uint8_t NB_TCP_ModuleInit(void)
{
    uint8_t  len, retry;
    uint16_t i;

    msg_printf("NB Reboot...");
    len = sprintf((char*)NBRXBUFF, "AT+NRB\r\n"); //reboot
    NBSEND(NBRXBUFF, len);
    HAL_Delay(3000);
    if (NB_CheckPoweron()) {
        msg_printf("NB Reboot...Done\r\n");
    } else {
        msg_printf("NB Reboot...Error\r\n");
        return 0;
    }

    i = 0;
    while (i < 100) {
        memset((uint8_t*)NBRXBUFF, 0, NB_BUFF_SIZE);
        NBRXFLAG = 0;
        len = sprintf((char*)NBRXBUFF, "AT+CGATT?\r\n");
        NBSEND(NBRXBUFF, len);
        retry = 0;
        while (!NBRXFLAG && retry < 10) {
            HAL_Delay(200);
            retry++;
        }
        if (NBRXFLAG) {
            NBRXFLAG = 0;
            if (strstr((char*)NBRXBUFF, (char*)"+CGATT:1")) {
                msg_printf("NB TCP init-waiting for Net...Done\r\n");
                break;
            }
        }
        i++;
        HAL_Delay(3000);
        msg_printf("NB TCP init-waiting for Net...\r\n");

        if (DEBUG_UART_RX.flag && DEBUG_UART_RX.len > 2) {
            //if dtu config cmd,just break.avoid waiting for too long.
            return 0;
        }
    }
    if (i == 100) {
        msg_printf("NB TCP init-waiting for Net...No Net Attachment\r\n");
        return 0;
    }
    HAL_Delay(100);
    retry = 0;
    while (!NB_TCP_Connect() && retry < 2) {
        retry++;
        HAL_Delay(500);
    }
    if (retry < 2) {
        if (RadioCfgInfo.Paras.NBTCP.Net == NET_UDP) {

            return 1;
        }
        msg_printf("NB_TCP Socket connect...Done\r\n");
        return 1;
    } else {
        if (RadioCfgInfo.Paras.NBTCP.Net == NET_UDP) {
            return 0;
        }
        msg_printf("NB_TCP Socket connect...Error\r\n");
        return 0;
    }
}

/**
  * @brief  This function is NB_TCP_SendFrame
  * @param  pHexdata, datalen
  * @retval 1:OK  0:Error
  */
uint8_t NB_TCP_SendFrame(uint8_t* pHexdata, uint16_t datalen)
{
    uint16_t i, len, retry;
    uint8_t  resend = 3;

    while (resend--) {
        //send failed.reinit module
        if (resend == 1) {
            NB_TCP_ModuleInit();
        }
        if (RadioCfgInfo.Paras.NBTCP.Net == NET_UDP) {
            len = sprintf((char*)NBHexStrTxBuffer, "AT+NSOST=%d,%d.%d.%d.%d,%d,%d,", socketid, RadioCfgInfo.Paras.NBTCP.IP1, RadioCfgInfo.Paras.NBTCP.IP2, RadioCfgInfo.Paras.NBTCP.IP3, RadioCfgInfo.Paras.NBTCP.IP4, RadioCfgInfo.Paras.NBTCP.Port, datalen);
        } else {
            len = sprintf((char*)NBHexStrTxBuffer, "AT+NSOSD=%d,%d,", socketid, datalen);
        }

        for (i = 0; i < datalen; i++) {
            sprintf((char*)(NBHexStrTxBuffer + len + 2 * i), "%x%x", *(pHexdata + i) >> 4, *(pHexdata + i) & 0x0f);
        }
        len += (datalen << 1);
        NBHexStrTxBuffer[len++] = 0x0d;
        NBHexStrTxBuffer[len++] = 0x0a;

        msg_printf("NB_SOCKET_PayLoad:");
        for (i = 0; i < len; i++) {
            msg_printf("%.2x ", NBHexStrTxBuffer[i]);
        }
        msg_printf("\r\n");

        NBSEND((uint8_t*)NBHexStrTxBuffer, len);
        memset(NBHexStrTxBuffer, 0, len);
        NBRXFLAG = 0;
        retry = 0;
        while ((!NBRXFLAG) && (retry < 200)) {
            retry++;
            HAL_Delay(10);
        }

        if (NBRXFLAG) {
            NBRXFLAG = 0;
            if (strstr((char*)NBRXBUFF, (char*)"OK")) {
                msg_printf("Send Done!\r\n");
                memset(NBRXBUFF, 0, NBRXLEN);
                return 1;
            }
        }
    }
    msg_printf("Send failed!\r\n");
    return 0;
}

/**
  * @brief  This function is NB_TCP_GetModuleBuffData
  * @param  None
  * @retval 1:OK  0:Error
  */
uint8_t NB_TCP_GetModuleBuffData(void)
{
    uint16_t dt = 0, i = 0;
    uint16_t len = 0;
    char*    pchar;
    uint8_t  temp8 = 0;
    NBRXFLAG = 0;

    len = sprintf((char*)NBHexStrTxBuffer, "AT+NSORF=%d,255\r\n", socketid);
    NBSEND((uint8_t*)NBHexStrTxBuffer, len);
    memset(NBHexStrTxBuffer, 0, len);

    while (!NBRXFLAG && dt < 100) {
        HAL_Delay(10);
        dt++;
    }
    if (NBRXLEN < NB_BUFF_SIZE) {
        NBRXBUFF[NBRXLEN] = 0;
    } else {
        return 0;
    }
    if (NBRXFLAG) {
        NBRXFLAG = 0;
        pchar = strstr((char*)NBRXBUFF, (char*)"+NSORF:");
        if (pchar != 0) {
            pchar = strtok((char*)NBRXBUFF, ",");
            i = 0;
            dt = 0;
            while (pchar != 0) {
                if (i == 3) {
                    NBPayLoadSize = (uint16_t)myatoi((char*)pchar, 5);
                    len = NBPayLoadSize;
                }
                if (i == 4) {
                    for (i = 0; i < len; i++) {
                        if (pchar[0] >= '0' && pchar[0] <= '9') {
                            temp8 = (pchar[0] - '0') << 4;
                        } else if (pchar[0] >= 'A' && pchar[0] <= 'F') {
                            temp8 = (pchar[0] - 'A' + 10) << 4;
                        } else if (pchar[0] >= 'a' && pchar[0] <= 'f') {
                            temp8 = (pchar[0] - 'a' + 10) << 4;
                        } else {
                            break;
                        }

                        if (pchar[1] >= '0' && pchar[1] <= '9') {
                            temp8 |= (pchar[1] - '0');
                        } else if (pchar[1] >= 'A' && pchar[1] <= 'F') {
                            temp8 |= (pchar[1] - 'A' + 10);
                        } else if (pchar[1] >= 'a' && pchar[1] <= 'f') {
                            temp8 |= (pchar[1] - 'a' + 10);
                        } else {
                            break;
                        }
                        NBPayLoad[i] = temp8;
                        pchar += 2;
                    }
                    if (i == len) {
                        return 1;
                    }
                }
                i++;
                pchar = strtok(0, ",");
            }
        }
    }
    return 0;
}
